# -*- coding: utf-8 -*-
"""
模块介绍:

创建者:

创建日期:
"""

# Standard Module
import json
import paramiko
import configparser
from functools import wraps
# Frame Module
from tornado.web import MissingArgumentError
from requests.exceptions import ConnectTimeout
# Custom Module
from config.settings import *

# from sqlalchemy.orm.query import Query



class AlchemyJsonEncoder():

    def __init__(self, obj_lis):

        self.obj_lis = obj_lis
        self.attr_lis = list()
        self.result_obj = dict()
        self.result_list = list()

    def default(self):
        for obj in self.obj_lis:
            # self.attr_lis = [x for x in dir(obj) if not x.startswith('_') and hasattr(x, '_decl_class_registry') is False and hasattr(x, '_sa_class_manager') is False and hasattr(x, '_sa_instance_state') is False and hasattr(x, 'metadata') is False]
            self.attr_lis = getattr(obj, '__attr__')
            for j in self.attr_lis:
                # print(j, getattr(obj, j))
                try:
                    self.result_obj[j] = getattr(obj, j)
                except TypeError:
                    self.result_obj[j] = None
            self.result_list.append(self.result_obj)
            self.result_obj = dict()
        return self.result_list


def attr_handle(models, iterms, value):

    if iterms in models.__attribution__.keys():
        if isinstance(getattr(models, '__attribution__')[iterms], int):
            return int(value)
        elif getattr(models, '__attribution__')[iterms] is 'utf-8':
            return value.encode('utf-8')
    else:
        return value


def utf_8(value):

    return value.encode()


class ParamikoClient(object):
    """

    """

    def __init__(self, config=None, config_api=None, priority=0):
        """

        :param priority:
                                        0 仅 config_api有效
                                        1 仅 config有效
                                        2 皆有效  config_api > config
                                        3 皆有效  config_api < config
        :param config:
        :param config_api: {
                                                'ssh': {
                                                                'host': IP
                                                                'port': 端口
                                                                'username'：ssh账户
                                                                'password'：ssh密码
                                                                }

                                                }

        """
        self.config_api = config_api
        if not self.config_api:
            self.config = configparser.ConfigParser()
            self.config.read(config)
        else:
            self.config = self.config_api
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.stdin, self.stdout, self.stderr = '', '', ''

    def connect(self):
        try:
            self.client.connect(
                hostname=self.config_api and self.config['ssh'].get('host') or self.config.get('ssh', 'host'),
                port=self.config_api and self.config['ssh'].get('port') or self.config.getint('ssh', 'port'),
                username=self.config_api and self.config['ssh'].get('username') or self.config.get('ssh', 'username'),
                password=self.config_api and self.config['ssh'].get('password') or self.config.get('ssh', 'password'),
                timeout=self.config_api and self.config['ssh'].get('timeout') or self.config.getfloat('ssh', 'timeout')
            )

        except Exception as e:
            print(e)
            try:
                self.client.close()
            except Exception as e:
                print(e)

    def run_cmd(self, cmd):
        self.stdin, self.stdout, self.stderr = self.client.exec_command(cmd)
        # for line in self.stdout:
        #     print(line)
        return self.stdout

    def sftp(self, src, dest):
        t = paramiko.Transport(sock=self.config['ssh'].get(
            'host') + ':' + str(self.config['ssh'].get('port')))
        t.connect(
            username=self.config['ssh'].get('username'),
            password=self.config['ssh'].get('password')
        )
        sftp = paramiko.SFTPClient.from_transport(t)
        # sftp.get('/home/fangliang/Desktop/data.txt','D:\\test.txt')    #下载文件
        sftp.put(src, dest)  # 上传文件

    def run_cmd_remote_quiek(self, cmd):
        self.connect()
        self.stdin, self.stdout, self.stderr = self.client.exec_command(cmd)
        # for line in self.stdout:
        # 	print(line)
        return [each_line for each_line in self.stdout]

    def __repr__(self):
        return self.stdin, self.stdout, self.stderr


def log_hande(log_content, log_template):
    _MATE = log_template.split('_')[0]
    content = dict()
    for meta, _ in LOGGING_META[_MATE].items():
        if _MATE == 'request' and meta == 'method':
            content.update({meta: log_content.method})
        elif _MATE == 'request' and meta == 'uri':
            content.update({meta: log_content.uri})
        elif _MATE == 'request' and meta == 'remote_ip':
            content.update({meta: log_content.remote_ip})
        elif _MATE == 'request' and meta == 'protocol':
            content.update({meta: log_content.protocol})
        else:
            if isinstance(log_content, dict):
                content.update({meta: log_content.get(meta, None)})
            # content.update({meta: log_content.get(meta)})
    return LOGGING_TEMPLATE[log_template] % content


def set_http_head(func):
    """
    跨站域防伪造
    :param func:
    :return:
    """
    logger = logging.getLogger('docker_cloud_manage_request')

    @wraps(func)
    def wrap(self):
        # 跨站域白名单
        self.set_header("Access-Control-Allow-Origin", "*")
        self.set_header("Content-Type", "application/json")
        try:
            log_content = log_hande(self.request, 'request_template_01')
            logger.info(log_content)
            return func(self)
        # except MissingArgumentError as e:
        #     self.write({'status_code': 501, 'status_text': json.dumps(e)})
        except ConnectTimeout as e:
            print(e)
            self.set_status(503, 'docker 节点 连接超时')
            self.write_error({'status_code': 502, 'status_text': json.dumps(e)})
        except Exception as e:
            # http 失败状态码
            print(e)
            self.set_status(502, 'docker 节点 版本查询 失败')
            self.write_error({'status_code': 502, 'status_text': json.dumps(e)})

    return wrap


def ver_size_auth(check_ver=None, checked_ver=None):
    """
    模块名称 ：版本高低校验
    参数： 校验版本与被校验版本
    """
    try:
        if check_ver is None:
            check_ver = []
        if checked_ver is None:
            checked_ver = []
        check_ver_len = len(check_ver)
        checked_ver_len = len(checked_ver)
        if check_ver_len != checked_ver_len:
            raise ValueError('版本号位数不一')
        else:
            # 同位填充
            for each_num in range(checked_ver_len):
                len_num = 0
                if len(str(checked_ver[each_num])) == len(
                        str(check_ver[each_num])):
                    continue
                elif len(str(checked_ver[each_num])) > len(str(check_ver[each_num])):
                    len_num = len(
                        str(checked_ver[each_num])) - len(str(check_ver[each_num]))
                    for each_ele in range(len_num):
                        check_ver[each_num] = '0' + check_ver[each_num]
                else:
                    len_num = len(
                        str(check_ver[each_num])) - len(str(checked_ver[each_num]))
                    checked_ver[each_num] = str(checked_ver[each_num])
                    for each_ele in range(len_num):
                        checked_ver[each_num] = '0' + checked_ver[each_num]
            # 版本比较 check_ver > checked_ver
            if int(''.join(checked_ver)) >= int(''.join(check_ver)):
                return True
            else:
                return False
    except Exception as e:
        print(str(e))


if __name__ == '__main__':
    #实例化SSHClient
    client = paramiko.SSHClient()
    #自动添加策略，保存服务器的主机名和密钥信息
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    #连接SSH服务端，以用户名和密码进行认证
    client.connect('192.168.43.116',username='root',password='qwer121212.')
    while True:
        inp = input('Lee@#')
        #打开一个Channel并执行命令
        stdin,stdout,stderr = client.exec_command(inp)
        #打印执行结果
        print (stdout.readlines())
    #关闭SSHClient
    client.close()
    # import paramiko
    # import interactive
    #
    # # log
    # paramiko.util.log_to_file('/tmp/test')
    #
    # #create ssh connection
    # ssh=paramiko.SSHClient()
    # ssh.load_system_host_keys()
    # ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # ssh.connect('10.1.6.190',port=22,username='root',password='xxxxxx',compress=True)
    #
    # #create interactive shell connection
    # channel=ssh.invoke_shell()
    #
    # #creat interactive pip
    # interactive.interactive_shell(channel)
    #
    # #close connection
    # channel.close()
    # ssh.close()




        # client = ParamikoClient(
        # 	# config = '../config.ini',
        # 	config_api = {
        # 		'ssh': {
        # 			'host': '192.168.43.116',
        # 			'port': 22,
        # 			'username': 'root',
        # 			'password': 'qwer121212.',
        # 			'timeout': 5.0
        # 			}
        # 	},
        # 	priority = 0
        #
        # )
        # client.connect()
        # # for line in client.run_cmd('date'):
        # # 	print(line)
        # while True:
        #     inp = input('Lee@#')
        #     print(inp)
        #     print (*client.run_cmd(inp))
        # 'host': '199.0.105.212',
        #                             'port': 22,
        #                             'username': 'client',
        #                             'password': '123456',
    # t = paramiko.Transport(sock=('192.168.1.220', 22))
    # t.connect(
    #     username='root',
    #     password='111111'
    # )
    # sftp = paramiko.SFTPClient.from_transport(t)
    # # sftp.get('/home/fangliang/Desktop/data.txt','D:\\test.txt')    #下载文件
    # sftp.put(
    #     r'F:\src\idea\BackendMonarch\upload_package\logo.ico',
    #     r'/home/logo.ico')  # 上传文件
    # t.close()
